home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Graphics / Gnuplot / Source / internal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-18  |  16.7 KB  |  899 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: internal.c,v 1.1.1.1 1993/03/18 03:37:15 davis Exp $";
  3. #endif
  4.  
  5.  
  6. /* GNUPLOT - internal.c */
  7. /*
  8.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  9.  *
  10.  * Permission to use, copy, and distribute this software and its
  11.  * documentation for any purpose with or without fee is hereby granted, 
  12.  * provided that the above copyright notice appear in all copies and 
  13.  * that both that copyright notice and this permission notice appear 
  14.  * in supporting documentation.
  15.  *
  16.  * Permission to modify the software is granted, but not the right to
  17.  * distribute the modified code.  Modifications are to be distributed 
  18.  * as patches to released version.
  19.  *  
  20.  * This software is provided "as is" without express or implied warranty.
  21.  * 
  22.  *
  23.  * AUTHORS
  24.  * 
  25.  *   Original Software:
  26.  *     Thomas Williams,  Colin Kelley.
  27.  * 
  28.  *   Gnuplot 2.0 additions:
  29.  *       Russell Lang, Dave Kotz, John Campbell.
  30.  *
  31.  *   Gnuplot 3.0 additions:
  32.  *       Gershon Elber and many others.
  33.  * 
  34.  * Send your comments or suggestions to 
  35.  *  info-gnuplot@dartmouth.edu.
  36.  * This is a mailing list; to join it send a note to 
  37.  *  info-gnuplot-request@dartmouth.edu.  
  38.  * Send bug reports to
  39.  *  bug-gnuplot@dartmouth.edu.
  40.  */
  41.  
  42. #include <math.h>
  43. #include <stdio.h>
  44. #include "plot.h"
  45.  
  46. TBOOLEAN undefined;
  47.  
  48. #ifndef AMIGA_SC_6_1
  49. char *strcpy();
  50. #endif /* !AMIGA_SC_6_1 */
  51.  
  52. struct value *pop(), *Gcomplex(), *Ginteger();
  53. double magnitude(), angle(), real();
  54.  
  55. struct value stack[STACK_DEPTH];
  56.  
  57. int s_p = -1;   /* stack pointer */
  58.  
  59.  
  60. /*
  61.  * System V and MSC 4.0 call this when they wants to print an error message.
  62.  * Don't!
  63.  */
  64. #ifndef _CRAY
  65. #if defined(MSDOS) || defined(DOS386)
  66. #ifdef __TURBOC__
  67. int matherr()    /* Turbo C */
  68. #else
  69. int matherr(x)    /* MSC 5.1 */
  70. struct exception *x;
  71. #endif /* TURBOC */
  72. #else /* not MSDOS */
  73. #ifdef apollo
  74. int matherr(struct exception *x)    /* apollo */
  75. #else /* apollo */
  76. #if defined(AMIGA_SC_6_1)||defined(ATARI)&&defined(__GNUC__)
  77. int matherr(x)    /* AMIGA_SC_6_1 */
  78. struct exception *x;
  79. #else    /* Most everyone else (not apollo). */
  80. int matherr()
  81. #endif /* AMIGA_SC_6_1 || GCC_ST */
  82. #endif /* apollo */
  83. #endif /* MSDOS */
  84. {
  85.     return (undefined = TRUE);        /* don't print error message */
  86. }
  87. #endif /* not _CRAY */
  88.  
  89.  
  90. reset_stack()
  91. {
  92.     s_p = -1;
  93. }
  94.  
  95.  
  96. check_stack()    /* make sure stack's empty */
  97. {
  98.     if (s_p != -1)
  99.         fprintf(stderr,"\nwarning:  internal error--stack not empty!\n");
  100. }
  101.  
  102.  
  103. struct value *pop(x)
  104. struct value *x;
  105. {
  106.     if (s_p  < 0 )
  107.         int_error("stack underflow",NO_CARET);
  108.     *x = stack[s_p--];
  109.     return(x);
  110. }
  111.  
  112.  
  113. push(x)
  114. struct value *x;
  115. {
  116.     if (s_p == STACK_DEPTH - 1)
  117.         int_error("stack overflow",NO_CARET);
  118.     stack[++s_p] = *x;
  119. }
  120.  
  121.  
  122. #define ERR_VAR "undefined variable: "
  123.  
  124. f_push(x)
  125. union argument *x;        /* contains pointer to value to push; */
  126. {
  127. static char err_str[sizeof(ERR_VAR) + MAX_ID_LEN] = ERR_VAR;
  128. struct udvt_entry *udv;
  129.  
  130.     udv = x->udv_arg;
  131.     if (udv->udv_undef) {     /* undefined */
  132.         (void) strcpy(&err_str[sizeof(ERR_VAR) - 1], udv->udv_name);
  133.         int_error(err_str,NO_CARET);
  134.     }
  135.     push(&(udv->udv_value));
  136. }
  137.  
  138.  
  139. f_pushc(x)
  140. union argument *x;
  141. {
  142.     push(&(x->v_arg));
  143. }
  144.  
  145.  
  146. f_pushd1(x)
  147. union argument *x;
  148. {
  149.     push(&(x->udf_arg->dummy_values[0]));
  150. }
  151.  
  152.  
  153. f_pushd2(x)
  154. union argument *x;
  155. {
  156.     push(&(x->udf_arg->dummy_values[1]));
  157. }
  158.  
  159.  
  160. f_pushd(x)
  161. union argument *x;
  162. {
  163. struct value param;
  164.     (void) pop(¶m);
  165.     push(&(x->udf_arg->dummy_values[param.v.int_val]));
  166. }
  167.  
  168.  
  169. #define ERR_FUN "undefined function: "
  170.  
  171. f_call(x)  /* execute a udf */
  172. union argument *x;
  173. {
  174. static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  175. register struct udft_entry *udf;
  176. struct value save_dummy;
  177.  
  178.     udf = x->udf_arg;
  179.     if (!udf->at) { /* undefined */
  180.         (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  181.                 udf->udf_name);
  182.         int_error(err_str,NO_CARET);
  183.     }
  184.     save_dummy = udf->dummy_values[0];
  185.     (void) pop(&(udf->dummy_values[0]));
  186.  
  187.     execute_at(udf->at);
  188.     udf->dummy_values[0] = save_dummy;
  189. }
  190.  
  191.  
  192. f_calln(x)  /* execute a udf of n variables */
  193. union argument *x;
  194. {
  195. static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  196. register struct udft_entry *udf;
  197. struct value save_dummy[MAX_NUM_VAR];
  198.  
  199.     int i;
  200.     int num_pop;
  201.     struct value num_params;
  202.  
  203.     udf = x->udf_arg;
  204.     if (!udf->at) { /* undefined */
  205.         (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  206.                 udf->udf_name);
  207.         int_error(err_str,NO_CARET);
  208.     }
  209.     for(i=0; i<MAX_NUM_VAR; i++) 
  210.         save_dummy[i] = udf->dummy_values[i];
  211.  
  212.     /* if there are more parameters than the function is expecting */
  213.     /* simply ignore the excess */
  214.     (void) pop(&num_params);
  215.  
  216.     if(num_params.v.int_val > MAX_NUM_VAR) {
  217.         /* pop the dummies that there is no room for */
  218.         num_pop = num_params.v.int_val - MAX_NUM_VAR;
  219.         for(i=0; i< num_pop; i++)
  220.             (void) pop(&(udf->dummy_values[i]));
  221.  
  222.         num_pop = MAX_NUM_VAR;
  223.     } else {
  224.         num_pop = num_params.v.int_val;
  225.     }
  226.  
  227.     /* pop parameters we can use */
  228.     for(i=num_pop-1; i>=0; i--)
  229.         (void) pop(&(udf->dummy_values[i]));
  230.  
  231.     execute_at(udf->at);
  232.     for(i=0; i<MAX_NUM_VAR; i++) 
  233.         udf->dummy_values[i] = save_dummy[i];
  234. }
  235.  
  236.  
  237. static int_check(v)
  238. struct value *v;
  239. {
  240.     if (v->type != INTGR)
  241.         int_error("non-integer passed to boolean operator",NO_CARET);
  242. }
  243.  
  244.  
  245. f_lnot()
  246. {
  247. struct value a;
  248.     int_check(pop(&a));
  249.     push(Ginteger(&a,!a.v.int_val) );
  250. }
  251.  
  252.  
  253. f_bnot()
  254. {
  255. struct value a;
  256.     int_check(pop(&a));
  257.     push( Ginteger(&a,~a.v.int_val) );
  258. }
  259.  
  260.  
  261. f_bool()
  262. {            /* converts top-of-stack to boolean */
  263.     int_check(&top_of_stack);
  264.     top_of_stack.v.int_val = !!top_of_stack.v.int_val;
  265. }
  266.  
  267.  
  268. f_lor()
  269. {
  270. struct value a,b;
  271.     int_check(pop(&b));
  272.     int_check(pop(&a));
  273.     push( Ginteger(&a,a.v.int_val || b.v.int_val) );
  274. }
  275.  
  276. f_land()
  277. {
  278. struct value a,b;
  279.     int_check(pop(&b));
  280.     int_check(pop(&a));
  281.     push( Ginteger(&a,a.v.int_val && b.v.int_val) );
  282. }
  283.  
  284.  
  285. f_bor()
  286. {
  287. struct value a,b;
  288.     int_check(pop(&b));
  289.     int_check(pop(&a));
  290.     push( Ginteger(&a,a.v.int_val | b.v.int_val) );
  291. }
  292.  
  293.  
  294. f_xor()
  295. {
  296. struct value a,b;
  297.     int_check(pop(&b));
  298.     int_check(pop(&a));
  299.     push( Ginteger(&a,a.v.int_val ^ b.v.int_val) );
  300. }
  301.  
  302.  
  303. f_band()
  304. {
  305. struct value a,b;
  306.     int_check(pop(&b));
  307.     int_check(pop(&a));
  308.     push( Ginteger(&a,a.v.int_val & b.v.int_val) );
  309. }
  310.  
  311.  
  312. f_uminus()
  313. {
  314. struct value a;
  315.     (void) pop(&a);
  316.     switch(a.type) {
  317.         case INTGR:
  318.             a.v.int_val = -a.v.int_val;
  319.             break;
  320.         case CMPLX:
  321.             a.v.cmplx_val.real =
  322.                 -a.v.cmplx_val.real;
  323.             a.v.cmplx_val.imag =
  324.                 -a.v.cmplx_val.imag;
  325.     }
  326.     push(&a);
  327. }
  328.  
  329.  
  330. f_eq() /* note: floating point equality is rare because of roundoff error! */
  331. {
  332. struct value a, b;
  333.     register int result;
  334.     (void) pop(&b);
  335.     (void) pop(&a);
  336.     switch(a.type) {
  337.         case INTGR:
  338.             switch (b.type) {
  339.                 case INTGR:
  340.                     result = (a.v.int_val ==
  341.                         b.v.int_val);
  342.                     break;
  343.                 case CMPLX:
  344.                     result = (a.v.int_val ==
  345.                         b.v.cmplx_val.real &&
  346.                        b.v.cmplx_val.imag == 0.0);
  347.             }
  348.             break;
  349.         case CMPLX:
  350.             switch (b.type) {
  351.                 case INTGR:
  352.                     result = (b.v.int_val == a.v.cmplx_val.real &&
  353.                        a.v.cmplx_val.imag == 0.0);
  354.                     break;
  355.                 case CMPLX:
  356.                     result = (a.v.cmplx_val.real==
  357.                         b.v.cmplx_val.real &&
  358.                         a.v.cmplx_val.imag==
  359.                         b.v.cmplx_val.imag);
  360.             }
  361.     }
  362.     push(Ginteger(&a,result));
  363. }
  364.  
  365.  
  366. f_ne()
  367. {
  368. struct value a, b;
  369.     register int result;
  370.     (void) pop(&b);
  371.     (void) pop(&a);
  372.     switch(a.type) {
  373.         case INTGR:
  374.             switch (b.type) {
  375.                 case INTGR:
  376.                     result = (a.v.int_val !=
  377.                         b.v.int_val);
  378.                     break;
  379.                 case CMPLX:
  380.                     result = (a.v.int_val !=
  381.                         b.v.cmplx_val.real ||
  382.                        b.v.cmplx_val.imag != 0.0);
  383.             }
  384.             break;
  385.         case CMPLX:
  386.             switch (b.type) {
  387.                 case INTGR:
  388.                     result = (b.v.int_val !=
  389.                         a.v.cmplx_val.real ||
  390.                        a.v.cmplx_val.imag != 0.0);
  391.                     break;
  392.                 case CMPLX:
  393.                     result = (a.v.cmplx_val.real !=
  394.                         b.v.cmplx_val.real ||
  395.                         a.v.cmplx_val.imag !=
  396.                         b.v.cmplx_val.imag);
  397.             }
  398.     }
  399.     push(Ginteger(&a,result));
  400. }
  401.  
  402.  
  403. f_gt()
  404. {
  405. struct value a, b;
  406.     register int result;
  407.     (void) pop(&b);
  408.     (void) pop(&a);
  409.     switch(a.type) {
  410.         case INTGR:
  411.             switch (b.type) {
  412.                 case INTGR:
  413.                     result = (a.v.int_val >
  414.                         b.v.int_val);
  415.                     break;
  416.                 case CMPLX:
  417.                     result = (a.v.int_val >
  418.                         b.v.cmplx_val.real);
  419.             }
  420.             break;
  421.         case CMPLX:
  422.             switch (b.type) {
  423.                 case INTGR:
  424.                     result = (a.v.cmplx_val.real >
  425.                         b.v.int_val);
  426.                     break;
  427.                 case CMPLX:
  428.                     result = (a.v.cmplx_val.real >
  429.                         b.v.cmplx_val.real);
  430.             }
  431.     }
  432.     push(Ginteger(&a,result));
  433. }
  434.  
  435.  
  436. f_lt()
  437. {
  438. struct value a, b;
  439.     register int result;
  440.     (void) pop(&b);
  441.     (void) pop(&a);
  442.     switch(a.type) {
  443.         case INTGR:
  444.             switch (b.type) {
  445.                 case INTGR:
  446.                     result = (a.v.int_val <
  447.                         b.v.int_val);
  448.                     break;
  449.                 case CMPLX:
  450.                     result = (a.v.int_val <
  451.                         b.v.cmplx_val.real);
  452.             }
  453.             break;
  454.         case CMPLX:
  455.             switch (b.type) {
  456.                 case INTGR:
  457.                     result = (a.v.cmplx_val.real <
  458.                         b.v.int_val);
  459.                     break;
  460.                 case CMPLX:
  461.                     result = (a.v.cmplx_val.real <
  462.                         b.v.cmplx_val.real);
  463.             }
  464.     }
  465.     push(Ginteger(&a,result));
  466. }
  467.  
  468.  
  469. f_ge()
  470. {
  471. struct value a, b;
  472.     register int result;
  473.     (void) pop(&b);
  474.     (void) pop(&a);
  475.     switch(a.type) {
  476.         case INTGR:
  477.             switch (b.type) {
  478.                 case INTGR:
  479.                     result = (a.v.int_val >=
  480.                         b.v.int_val);
  481.                     break;
  482.                 case CMPLX:
  483.                     result = (a.v.int_val >=
  484.                         b.v.cmplx_val.real);
  485.             }
  486.             break;
  487.         case CMPLX:
  488.             switch (b.type) {
  489.                 case INTGR:
  490.                     result = (a.v.cmplx_val.real >=
  491.                         b.v.int_val);
  492.                     break;
  493.                 case CMPLX:
  494.                     result = (a.v.cmplx_val.real >=
  495.                         b.v.cmplx_val.real);
  496.             }
  497.     }
  498.     push(Ginteger(&a,result));
  499. }
  500.  
  501.  
  502. f_le()
  503. {
  504. struct value a, b;
  505.     register int result;
  506.     (void) pop(&b);
  507.     (void) pop(&a);
  508.     switch(a.type) {
  509.         case INTGR:
  510.             switch (b.type) {
  511.                 case INTGR:
  512.                     result = (a.v.int_val <=
  513.                         b.v.int_val);
  514.                     break;
  515.                 case CMPLX:
  516.                     result = (a.v.int_val <=
  517.                         b.v.cmplx_val.real);
  518.             }
  519.             break;
  520.         case CMPLX:
  521.             switch (b.type) {
  522.                 case INTGR:
  523.                     result = (a.v.cmplx_val.real <=
  524.                         b.v.int_val);
  525.                     break;
  526.                 case CMPLX:
  527.                     result = (a.v.cmplx_val.real <=
  528.                         b.v.cmplx_val.real);
  529.             }
  530.     }
  531.     push(Ginteger(&a,result));
  532. }
  533.  
  534.  
  535. f_plus()
  536. {
  537. struct value a, b, result;
  538.     (void) pop(&b);
  539.     (void) pop(&a);
  540.     switch(a.type) {
  541.         case INTGR:
  542.             switch (b.type) {
  543.                 case INTGR:
  544.                     (void) Ginteger(&result,a.v.int_val +
  545.                         b.v.int_val);
  546.                     break;
  547.                 case CMPLX:
  548.                     (void) Gcomplex(&result,a.v.int_val +
  549.                         b.v.cmplx_val.real,
  550.                        b.v.cmplx_val.imag);
  551.             }
  552.             break;
  553.         case CMPLX:
  554.             switch (b.type) {
  555.                 case INTGR:
  556.                     (void) Gcomplex(&result,b.v.int_val +
  557.                         a.v.cmplx_val.real,
  558.                        a.v.cmplx_val.imag);
  559.                     break;
  560.                 case CMPLX:
  561.                     (void) Gcomplex(&result,a.v.cmplx_val.real+
  562.                         b.v.cmplx_val.real,
  563.                         a.v.cmplx_val.imag+
  564.                         b.v.cmplx_val.imag);
  565.             }
  566.     }
  567.     push(&result);
  568. }
  569.  
  570.  
  571. f_minus()
  572. {
  573. struct value a, b, result;
  574.     (void) pop(&b);
  575.     (void) pop(&a);        /* now do a - b */
  576.     switch(a.type) {
  577.         case INTGR:
  578.             switch (b.type) {
  579.                 case INTGR:
  580.                     (void) Ginteger(&result,a.v.int_val -
  581.                         b.v.int_val);
  582.                     break;
  583.                 case CMPLX:
  584.                     (void) Gcomplex(&result,a.v.int_val -
  585.                         b.v.cmplx_val.real,
  586.                        -b.v.cmplx_val.imag);
  587.             }
  588.             break;
  589.         case CMPLX:
  590.             switch (b.type) {
  591.                 case INTGR:
  592.                     (void) Gcomplex(&result,a.v.cmplx_val.real -
  593.                         b.v.int_val,
  594.                         a.v.cmplx_val.imag);
  595.                     break;
  596.                 case CMPLX:
  597.                     (void) Gcomplex(&result,a.v.cmplx_val.real-
  598.                         b.v.cmplx_val.real,
  599.                         a.v.cmplx_val.imag-
  600.                         b.v.cmplx_val.imag);
  601.             }
  602.     }
  603.     push(&result);
  604. }
  605.  
  606.  
  607. f_mult()
  608. {
  609. struct value a, b, result;
  610.     (void) pop(&b);
  611.     (void) pop(&a);    /* now do a*b */
  612.  
  613.     switch(a.type) {
  614.         case INTGR:
  615.             switch (b.type) {
  616.                 case INTGR:
  617.                     (void) Ginteger(&result,a.v.int_val *
  618.                         b.v.int_val);
  619.                     break;
  620.                 case CMPLX:
  621.                     (void) Gcomplex(&result,a.v.int_val *
  622.                         b.v.cmplx_val.real,
  623.                         a.v.int_val *
  624.                         b.v.cmplx_val.imag);
  625.             }
  626.             break;
  627.         case CMPLX:
  628.             switch (b.type) {
  629.                 case INTGR:
  630.                     (void) Gcomplex(&result,b.v.int_val *
  631.                         a.v.cmplx_val.real,
  632.                         b.v.int_val *
  633.                         a.v.cmplx_val.imag);
  634.                     break;
  635.                 case CMPLX:
  636.                     (void) Gcomplex(&result,a.v.cmplx_val.real*
  637.                         b.v.cmplx_val.real-
  638.                         a.v.cmplx_val.imag*
  639.                         b.v.cmplx_val.imag,
  640.                         a.v.cmplx_val.real*
  641.                         b.v.cmplx_val.imag+
  642.                         a.v.cmplx_val.imag*
  643.                         b.v.cmplx_val.real);
  644.             }
  645.     }
  646.     push(&result);
  647. }
  648.  
  649.  
  650. f_div()
  651. {
  652. struct value a, b, result;
  653. register double square;
  654.     (void) pop(&b);
  655.     (void) pop(&a);    /* now do a/b */
  656.  
  657.     switch(a.type) {
  658.         case INTGR:
  659.             switch (b.type) {
  660.                 case INTGR:
  661.                     if (b.v.int_val)
  662.                       (void) Ginteger(&result,a.v.int_val /
  663.                         b.v.int_val);
  664.                     else {
  665.                       (void) Ginteger(&result,0);
  666.                       undefined = TRUE;
  667.                     }
  668.                     break;
  669.                 case CMPLX:
  670.                     square = b.v.cmplx_val.real*
  671.                         b.v.cmplx_val.real +
  672.                         b.v.cmplx_val.imag*
  673.                         b.v.cmplx_val.imag;
  674.                     if (square)
  675.                         (void) Gcomplex(&result,a.v.int_val*
  676.                         b.v.cmplx_val.real/square,
  677.                         -a.v.int_val*
  678.                         b.v.cmplx_val.imag/square);
  679.                     else {
  680.                         (void) Gcomplex(&result,0.0,0.0);
  681.                         undefined = TRUE;
  682.                     }
  683.             }
  684.             break;
  685.         case CMPLX:
  686.             switch (b.type) {
  687.                 case INTGR:
  688.                     if (b.v.int_val)
  689.                       
  690.                       (void) Gcomplex(&result,a.v.cmplx_val.real/
  691.                         b.v.int_val,
  692.                         a.v.cmplx_val.imag/
  693.                         b.v.int_val);
  694.                     else {
  695.                         (void) Gcomplex(&result,0.0,0.0);
  696.                         undefined = TRUE;
  697.                     }
  698.                     break;
  699.                 case CMPLX:
  700.                     square = b.v.cmplx_val.real*
  701.                         b.v.cmplx_val.real +
  702.                         b.v.cmplx_val.imag*
  703.                         b.v.cmplx_val.imag;
  704.                     if (square)
  705.                     (void) Gcomplex(&result,(a.v.cmplx_val.real*
  706.                         b.v.cmplx_val.real+
  707.                         a.v.cmplx_val.imag*
  708.                         b.v.cmplx_val.imag)/square,
  709.                         (a.v.cmplx_val.imag*
  710.                         b.v.cmplx_val.real-
  711.                         a.v.cmplx_val.real*
  712.                         b.v.cmplx_val.imag)/
  713.                             square);
  714.                     else {
  715.                         (void) Gcomplex(&result,0.0,0.0);
  716.                         undefined = TRUE;
  717.                     }
  718.             }
  719.     }
  720.     push(&result);
  721. }
  722.  
  723.  
  724. f_mod()
  725. {
  726. struct value a, b;
  727.     (void) pop(&b);
  728.     (void) pop(&a);    /* now do a%b */
  729.  
  730.     if (a.type != INTGR || b.type != INTGR)
  731.         int_error("can only mod ints",NO_CARET);
  732.     if (b.v.int_val)
  733.         push(Ginteger(&a,a.v.int_val % b.v.int_val));
  734.     else {
  735.         push(Ginteger(&a,0));
  736.         undefined = TRUE;
  737.     }
  738. }
  739.  
  740.  
  741. f_power()
  742. {
  743. struct value a, b, result;
  744. register int i, t, count;
  745. register double mag, ang;
  746.     (void) pop(&b);
  747.     (void) pop(&a);    /* now find a**b */
  748.  
  749.     switch(a.type) {
  750.         case INTGR:
  751.             switch (b.type) {
  752.                 case INTGR:
  753.                     count = abs(b.v.int_val);
  754.                     t = 1;
  755.                     for(i = 0; i < count; i++)
  756.                         t *= a.v.int_val;
  757.                     if (b.v.int_val >= 0)
  758.                         (void) Ginteger(&result,t);
  759.                     else
  760.                       if (t != 0)
  761.                         (void) Gcomplex(&result,1.0/t,0.0);
  762.                       else {
  763.                          undefined = TRUE;
  764.                          (void) Gcomplex(&result, 0.0, 0.0);
  765.                       }
  766.                     break;
  767.                 case CMPLX:
  768.                     mag =
  769.                       pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  770.                     if (b.v.cmplx_val.real < 0.0)
  771.                       if (mag != 0.0)
  772.                         mag = 1.0/mag;
  773.                       else 
  774.                         undefined = TRUE;
  775.                     mag *= exp(-b.v.cmplx_val.imag*angle(&a));
  776.                     ang = b.v.cmplx_val.real*angle(&a) +
  777.                           b.v.cmplx_val.imag*log(magnitude(&a));
  778.                     (void) Gcomplex(&result,mag*cos(ang),
  779.                         mag*sin(ang));
  780.             }
  781.             break;
  782.         case CMPLX:
  783.             switch (b.type) {
  784.                 case INTGR:
  785.                     if (a.v.cmplx_val.imag == 0.0) {
  786.                         mag = pow(a.v.cmplx_val.real,(double)abs(b.v.int_val));
  787.                         if (b.v.int_val < 0)
  788.                           if (mag != 0.0)
  789.                             mag = 1.0/mag;
  790.                           else 
  791.                             undefined = TRUE;
  792.                         (void) Gcomplex(&result,mag,0.0);
  793.                     }
  794.                     else {
  795.                         /* not so good, but...! */
  796.                         mag = pow(magnitude(&a),(double)abs(b.v.int_val));
  797.                         if (b.v.int_val < 0)
  798.                           if (mag != 0.0)
  799.                             mag = 1.0/mag;
  800.                           else 
  801.                             undefined = TRUE;
  802.                         ang = angle(&a)*b.v.int_val;
  803.                         (void) Gcomplex(&result,mag*cos(ang),
  804.                             mag*sin(ang));
  805.                     }
  806.                     break;
  807.                 case CMPLX:
  808.                     mag = pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  809.                     if (b.v.cmplx_val.real < 0.0)
  810.                       if (mag != 0.0)
  811.                         mag = 1.0/mag;
  812.                       else 
  813.                         undefined = TRUE;
  814.                     mag *= exp(-b.v.cmplx_val.imag*angle(&a));
  815.                     ang = b.v.cmplx_val.real*angle(&a) +
  816.                           b.v.cmplx_val.imag*log(magnitude(&a));
  817.                     (void) Gcomplex(&result,mag*cos(ang),
  818.                         mag*sin(ang));
  819.             }
  820.     }
  821.     push(&result);
  822. }
  823.  
  824.  
  825. f_factorial()
  826. {
  827. struct value a;
  828. register int i;
  829. register double val;
  830.  
  831.     (void) pop(&a);    /* find a! (factorial) */
  832.  
  833.     switch (a.type) {
  834.         case INTGR:
  835.             val = 1.0;
  836.             for (i = a.v.int_val; i > 1; i--)  /*fpe's should catch overflows*/
  837.                 val *= i;
  838.             break;
  839.         default:
  840.             int_error("factorial (!) argument must be an integer",
  841.             NO_CARET);
  842.         }
  843.  
  844.     push(Gcomplex(&a,val,0.0));
  845.             
  846. }
  847.  
  848.  
  849. int
  850. f_jump(x)
  851. union argument *x;
  852. {
  853.     return(x->j_arg);
  854. }
  855.  
  856.  
  857. int
  858. f_jumpz(x)
  859. union argument *x;
  860. {
  861. struct value a;
  862.     int_check(&top_of_stack);
  863.     if (top_of_stack.v.int_val) {    /* non-zero */
  864.         (void) pop(&a);
  865.         return 1;                /* no jump */
  866.     }
  867.     else
  868.         return(x->j_arg);        /* leave the argument on TOS */
  869. }
  870.  
  871.  
  872. int
  873. f_jumpnz(x)
  874. union argument *x;
  875. {
  876. struct value a;
  877.     int_check(&top_of_stack);
  878.     if (top_of_stack.v.int_val)    /* non-zero */
  879.         return(x->j_arg);        /* leave the argument on TOS */
  880.     else {
  881.         (void) pop(&a);
  882.         return 1;                /* no jump */
  883.     }
  884. }
  885.  
  886.  
  887. int
  888. f_jtern(x)
  889. union argument *x;
  890. {
  891. struct value a;
  892.  
  893.     int_check(pop(&a));
  894.     if (a.v.int_val)
  895.         return(1);                /* no jump; fall through to TRUE code */
  896.     else
  897.         return(x->j_arg);        /* go jump to FALSE code */
  898. }
  899.